package com.common.util;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.greenrobot.eventbus.EventBus;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.SocketTimeoutException;
import java.security.KeyStore;
import java.util.List;
import java.util.concurrent.TimeoutException;

import javax.net.ssl.SSLHandshakeException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class UtilHttp {
	final static String TAG = "UtilHttp";

	public static final int TIME_OUT = 0;
	public static final int ERROR_EXCEPTION = 1;

	private static final int SO_TIMEOUT = 30 * 1000; // 设置等待数据超时时间x秒钟

	public static HttpClient getHttpClient() {
		try {
			KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
			trustStore.load(null, null);
			SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);

			sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); // 允许所有主机的验证
			HttpParams params = new BasicHttpParams();
			HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
			HttpProtocolParams.setContentCharset(params, "UTF-8");
			HttpProtocolParams.setUseExpectContinue(params, false);// 设置为true会多一次请求确认，增加整个请求的时长，本项目用不上。
			HttpConnectionParams.setConnectionTimeout(params, SO_TIMEOUT);// 设置连接超时
			HttpConnectionParams.setSoTimeout(params, SO_TIMEOUT);// 设置socket超时

			// 设置http https支持
			SchemeRegistry schReg = new SchemeRegistry();
			schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
			schReg.register(new Scheme("https", sf, 443));

			ClientConnectionManager conManager = new ThreadSafeClientConnManager(params, schReg);
			return new DefaultHttpClient(conManager, params);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static BufferedInputStream executeGetReturnInputStream(String oriUrl){
		if (TextUtils.isEmpty(oriUrl)) {
			return null;
		}

		String url = Util.encodeURL(oriUrl);
		//Log.d(TAG, "executeGet ori oriUrl = \r\n" + url + " --->\r\n" + url);
		Log.d(TAG, "executeGetReturnInputStream  url = " + url);
		StringBuffer sbResult = new StringBuffer();
		HttpClient client = getHttpClient();
		BufferedInputStream ret = null;

		try {

			HttpGet httpGet = new HttpGet(url);
			//httpGet.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); 
			httpGet.addHeader("User-Agent", "sunniwell@tvb");
			HttpResponse response = client.execute(httpGet);
			if (response == null) {
				Log.d(TAG, "executeGetReturnInputStream url = " + url + "response = " + response);
				ret = null;
			} else {
				InputStream inputStream = response.getEntity().getContent();
				ret = new BufferedInputStream(inputStream);
				if(ret != null){
					Log.d(TAG, "executeGetReturnInputStream ret.available() = "+ret.available());
				}
			}
		}catch (Exception e) {
			Log.d(TAG, "executeGetReturnInputStream got Exception." + e.getClass().getName() + " url= " + url);
			e.printStackTrace();
		}

		return ret;
	}
	public static String executeGet(String oriUrl, List<BasicHeader> dataList) {
		// 防止回溯
		if (TextUtils.isEmpty(oriUrl)) {
			return "";
		}

		String url = Util.encodeURL(oriUrl);
		//Log.d(TAG, "executeGet ori oriUrl = \r\n" + url + " --->\r\n" + url);
		Log.d(TAG, "executeGet  url = " + url);
		StringBuffer sbResult = new StringBuffer();
		HttpClient client = getHttpClient();
		String ret = null;

		try {

			if (dataList != null && dataList.size() > 0) {
				url += "?";
				for (BasicHeader h : dataList) {
					url += h.getName() + "=" + h.getValue() + "&";
				}
			}
			HttpGet httpGet = new HttpGet(url);
			//httpGet.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); 
			httpGet.addHeader("User-Agent", "sunniwell@tvb");
			HttpResponse response = client.execute(httpGet);
			if (response == null) {
				Log.d(TAG, "executeGet url = " + url + "response = " + response);

				ret = null;
			} else {
				sbResult = getResponse(sbResult, response);
				Log.d(TAG, "executeGet url = " + url + "  StatusCode:" + response.getStatusLine().getStatusCode());
				if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {

					ret = null;
				} else {
					ret = sbResult.toString();
					if (TextUtils.isEmpty(ret)) {// 200 OK but no data...
						Log.d(TAG, "url = " + url + "  no data....");

					}
				}
			}
		} catch (TimeoutException e) {
			Log.d(TAG, "executeGet TimeoutException..url = " + url);

		} catch (SocketTimeoutException e) {
			Log.d(TAG, "executeGet SocketTimeoutException..url = " + url);

		} catch (ConnectTimeoutException e) {
			Log.d(TAG, "executeGet ConnectTimeoutException..url= " + url);

		}catch(SSLHandshakeException e){
			Log.d(TAG, "executeGet  SSLHandshakeException .url= " + url);

		} catch (Exception e) {
			Log.d(TAG, "executeGet got Exception." + e.getClass().getName() + " url= " + url);

			e.printStackTrace();
		} finally {
			client.getConnectionManager().shutdown();
		}

		return ret;
	}

	public static String executePost(String url, List<BasicNameValuePair> dataList) {
		StringBuffer sbResult = new StringBuffer();
		HttpClient client = getHttpClient();
		String ret = null;
		try {

			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); 
			httpPost.addHeader("User-Agent", "sunniwell@tvb");
			HttpEntity entity = new UrlEncodedFormEntity(dataList, "UTF-8");
			httpPost.setEntity(entity);
			HttpResponse response = client.execute(httpPost);
			sbResult = getResponse(sbResult, response);
			Log.d(TAG, "executePost url = " + url + "StatusCode:" + response.getStatusLine().getStatusCode());
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				ret = null;
			} else {
				ret = sbResult.toString();
				if (TextUtils.isEmpty(ret)) {// 200 OK but no data...
					//ret = NO_DATA;
				}
			}
			Log.d(TAG, "executePost ret = " + ret);
		} catch (TimeoutException e) {
			Log.d(TAG, "executePost TimeoutException..url = " + url);
		} catch (SocketTimeoutException e) {
			Log.d(TAG, "executePost SocketTimeoutException..url = " + url);
		} catch (ConnectTimeoutException e) {
			Log.d(TAG, "executePost ConnectTimeoutException..url = " + url);
		} catch (Exception e) {
			Log.d(TAG, "executePost got Exception." + e.getClass().getName() + " url= " + url);
			e.printStackTrace();
		} finally {
			//client.getConnectionManager().shutdown();
		}
		return ret;
	}

	public static String executePostJson(String url, String json) {
		StringBuffer sbResult = new StringBuffer();
		HttpClient client = getHttpClient();
		try {

			if (Util.isEmpty(json) || Util.isEmpty(url)) {
				Log.e(TAG, "executePostJson parameter error url = "+url+ " json = \r\n " + json);
				return null;
			}
			if(!url.contains("/bos/login")){
				Log.d(TAG, "executePostJson url = " + url + " json = \r\n " + json);
			}
			HttpPost httpPost = new HttpPost(url);
			httpPost.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE); 
			StringEntity s = new StringEntity(json);
			s.setContentEncoding("UTF-8");
			s.setContentType("application/json");
			httpPost.setEntity(s);
			HttpResponse response = client.execute(httpPost);
			if (response == null) {
				Log.e(TAG, "executePostJson response == null");
				return null;
			}
			if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
				Log.e(TAG, "executePostJson response.getStatusLine().getStatusCode() = "
						+ response.getStatusLine().getStatusCode());
				return null;
			}
			sbResult = getResponse(sbResult, response);
			if(!url.contains("/bos/login")){
				Log.d(TAG, "executePostJson url = " + url + "" +
						" StatusCode:" + response.getStatusLine().getStatusCode()
						+ "\r\n ret = " + sbResult.toString());
				//LogsManager.getInstance().sendLoopCommonInfoLog("executePostJson ok url= " + url);
				if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK && TextUtils.isEmpty(sbResult.toString())) {
					return "true";
				}
			}
			return sbResult.toString();
		} catch (SocketTimeoutException e) {

			Log.d(TAG, "executePostJson SocketTimeoutException..");
		} catch (ConnectTimeoutException e) {

			Log.d(TAG, "executePostJson ConnectTimeoutException..");
		}catch(SSLHandshakeException e){

			Log.d(TAG, "executePostJson  SSLHandshakeException  ...");
		}catch (Exception e) {

			Log.d(TAG, "executePostJson got Exception." + e.getClass().getName() + " url= " + url );
			e.printStackTrace();
		}finally {
			//client.getConnectionManager().shutdown();
		}
		return null;
	}

	public static boolean executeGetSaveFile(String url, File saveFile) {
		try {
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
			HttpConnectionParams.setSoTimeout(httpParams, 5000);
			DefaultHttpClient client = new DefaultHttpClient(httpParams);
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = client.execute(httpGet);
			if (response.getStatusLine().getStatusCode() == 200) {
				saveFile.deleteOnExit();
				saveFile.createNewFile();
				BufferedReader inputStream = new BufferedReader(
						new InputStreamReader(response.getEntity().getContent(), "utf-8"));
				OutputStreamWriter outputStream = new OutputStreamWriter(new FileOutputStream(saveFile), "utf-8");
				String buffer = "";
				while ((buffer = inputStream.readLine()) != null) {
					outputStream.write(buffer);
				}
				inputStream.close();
				outputStream.close();
				return true;
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	private static StringBuffer getResponse(StringBuffer sbResult, HttpResponse response) throws Exception {
		InputStream inputStream = response.getEntity().getContent();
		BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
		String data = "";
		if (sbResult.toString().equalsIgnoreCase("")) {
			while ((data = br.readLine()) != null) {
				sbResult.append(data + "\r\n");
			}
		}
		inputStream.close();
		return sbResult;

	}

	private static StringBuffer getResponseGBK(StringBuffer sbResult, HttpResponse response) throws Exception {
		InputStream inputStream = response.getEntity().getContent();
		BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "GBK"));// 获得真实播放地址时是GBK编码的xml
		String data = "";
		if (sbResult.toString().equalsIgnoreCase("")) {
			while ((data = br.readLine()) != null) {
				sbResult.append(data + "\r\n");
			}
		}
		inputStream.close();
		return sbResult;

	}

    public static void download(Context c,String url, String saveFileName) {

        Request request = new Request.Builder()
                .url(url)
                .build();

        OkHttpClient client = new OkHttpClient();

        try {
            Response response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //异步请求
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败监听回调
                Log.e(TAG,"onFailure ...");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                File saveFile = UtilFile.getCacheFile(c,saveFileName);
                if(saveFile.exists()){
                    saveFile.delete();
                }

                try {
                    saveFile.createNewFile();
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    fos = new FileOutputStream(saveFile);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        //下载中更新进度条
                    }
                    fos.flush();
                    //下载完成
                    EventBus.getDefault().post(new DownloadProgressEvent("finish", total, total));
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {

                    try {
                        if (is != null) {
                            is.close();
                        }
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {

                    }
                }

            }
        });
    }


/*
    public static boolean download1(Context c,String url, String saveFileName) {

        File saveFile = UtilFile.getCacheFile(c,saveFileName);
		try {
		    Log.d(TAG,"download : saveFileName = "+saveFileName);
			BasicHttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
			HttpConnectionParams.setSoTimeout(httpParams, 10000);
			DefaultHttpClient client = new DefaultHttpClient(httpParams);
			HttpGet httpGet = new HttpGet(url);
            Log.d(TAG,"download : saveFile = "+saveFile.getAbsolutePath());

			String name = saveFile.getName();
			HttpResponse response = client.execute(httpGet);
			if (response.getStatusLine().getStatusCode() == 200) {
                saveFile.deleteOnExit();
                saveFile.createNewFile();
				InputStream input = response.getEntity().getContent();
				FileOutputStream output = new FileOutputStream(saveFile);
				int total = (int) response.getEntity().getContentLength();
				byte[] b = new byte[4096];
				int read = 0;
				int lastProgress = 0;
				while (true) {
					int ret = input.read(b, 0, b.length);
					if (ret < 0)
						break;

					if (ret > 0) {
						read += ret;
						output.write(b, 0, ret);
					}
					if (read * 100 / total == lastProgress) {
						lastProgress += 5;
						//EventBus.getDefault().post(new DownloadProgressEvent(name, total, read));
					}
				}
				input.close();
				output.close();
				client.getConnectionManager().shutdown();
				if (read < total) {
					saveFile.deleteOnExit();
					return false;
				}
                EventBus.getDefault().post(new DownloadProgressEvent("finish", total, read));
				return true;
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			saveFile.deleteOnExit();
			return false;
		}
	}

*/

//	public static boolean isEmpty(String jsonResult) {
//		if (jsonResult == null || jsonResult.trim().equals("") || jsonResult.trim().equals("{}")
//				|| jsonResult.startsWith("invalid") || jsonResult.startsWith(NO_DATA)) {
//			return true;
//		}
//
//		return false;
//	}

}
